home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 026-050 / scopedisk47 / ls22 / c2.a < prev    next >
Text File  |  1995-03-18  |  9KB  |  396 lines

  1. *
  2. * C initial startup procedure under AmigaDOS
  3. * Use the following command line to make c.o
  4. * asm -u -iINCLUDE: c.a
  5. *
  6. * Use the following command line to make cres.o
  7. * asm -u -dRESIDENT -iINCLUDE: -ocres.o c.a
  8.  
  9.     BASEREG    B
  10.     SMALLOBJ
  11.     ADDSYM
  12.     OPTIMON
  13.  
  14.     IDNT    "c2.a"
  15.  
  16. * --------------------------------------------------------------------- *
  17. * Macros:
  18. * --------------------------------------------------------------------- *
  19. SYS    MACRO    *
  20.     IFGT    NARG-2
  21.     FAIL    !!!
  22.     ENDC
  23.     IFEQ    NARG-2
  24.     MOVE.L    \2,a6
  25.     ENDC
  26.     JSR    _LVO\1(a6)
  27.     ENDM
  28.  
  29. XLVO    MACRO    *
  30.     XREF    _LVO\1
  31.     ENDM
  32.  
  33. * --------------------------------------------------------------------- *
  34. * Equates:
  35. * --------------------------------------------------------------------- *
  36. RESIDENT    EQU    1
  37.  
  38. MEMF_PUBLIC    EQU    $1
  39. MEMF_CLEAR    EQU    $10000
  40. MEMFLAGS    EQU    MEMF_CLEAR+MEMF_PUBLIC
  41. AbsExecBase    EQU    $0004
  42. cli_CommandName    EQU    $10
  43. pr_CLI        EQU    $AC
  44. pr_CurrentDir    EQU    $98
  45. ThisTask    EQU    $114
  46.  
  47. _LVOCloseLibrary EQU    $FE62
  48. _LVOAllocMem    EQU    $FF3A
  49. _LVOFreeMem    EQU    $FF2E
  50. _LVOSetSignal    EQU    $FECE
  51. _LVOOpenLibrary    EQU    $FDD8
  52.  
  53.     XREF    _DOSBase
  54.     XREF    _LinkerDB        ; linker defined base value
  55.     XREF    __BSSBAS        ; linker defined base of BSS
  56.     XREF    __BSSLEN        ; linker defined length of BSS
  57.  
  58.      IFD    RESIDENT
  59.     XREF    _RESLEN
  60.     XREF    _RESBASE
  61.     XREF    _NEWDATAL
  62.      ENDC
  63.     
  64.     XREF    __main            ; Name of C program to start with.
  65.     XREF    _MemCleanup        ; Free all allocated memory
  66.     XREF    ___fpinit        ; initialize floating point
  67.     XREF    ___fpterm        ; terminate floating point
  68.  
  69. * --------------------------------------------------------------------- *
  70.     SECTION    TEXT,CODE
  71. * --------------------------------------------------------------------- *
  72.     XDEF    zzstart
  73. zzstart:
  74.     move.l    a0,a2            ; save command pointer
  75.     move.l    d0,d2            ; and command length
  76.     lea    _LinkerDB,a4        ; load base register
  77.  
  78.      IFND    RESIDENT
  79.     lea    __BSSBAS,a3        ; get base of BSS
  80.     moveq    #0,d1
  81.     move.l    #__BSSLEN,d0        ; get length of BSS in longwords
  82.      bra.b    clr_lp             ; and clear for length given
  83. clr_bss move.l    d1,(a3)+
  84. clr_lp    dbf    d0,clr_bss
  85.      ENDC
  86.  
  87.      IFD    RESIDENT
  88.     movea.l    AbsExecBase,a6
  89.  
  90.     movem.l    d0-d1/a0-a2,-(sp)
  91.     sub.l    #_RESBASE,a4
  92.     move.l    #_RESLEN,d0
  93.     move.l    #MEMFLAGS,d1
  94.     SYS    AllocMem
  95.     tst.l    d0
  96.      beq.w    abort
  97.     move.l    d0,a0
  98.     move.l     d0,a2
  99.  
  100. ;a2 now has difference
  101.     move.l    d0,a1
  102.     move.l    #_NEWDATAL,d0
  103. ;copy data over
  104. cpy:    move.l    (a4)+,(a0)+
  105.     subq.l    #1,d0
  106.      bne.b    cpy
  107. ;a4 now points at number of relocs
  108.     move.l    (a4)+,d0
  109. reloc:     beq.b    nreloc
  110.     move.l    a1,a0
  111.     add.l    (a4)+,a0        ; a0 now has add of reloc
  112.     add.l    (a0),a2
  113.     move.l    a2,(a0) 
  114.     move.l    a1,a2            ; restore offset
  115.     subq.l    #1,d0
  116.     bra.b    reloc
  117.     
  118. nreloc: move.l    a1,a4            ; set up new base register
  119.     add.l    #_RESBASE,a4
  120.     movem.l    (sp)+,d0-d1/a0-a2
  121.      ENDC
  122.  
  123.     movea.l    AbsExecBase,a6
  124.     move.l    a6,_SysBase(a4)
  125.     move.l    sp,__StackPtr(a4)    ; Save stack ptr
  126.     clr.l    _WBenchMsg(a4)
  127.  
  128. * get the address of our task
  129.     move.l    ThisTask(a6),a3
  130.  
  131. * clear any pending signals
  132.     moveq    #0,d0
  133.     move.l    #$00003000,d1
  134.     SYS    SetSignal
  135.     
  136. * are we running as a son of Workbench?
  137.     move.l    pr_CurrentDir(a3),_curdir(a4)
  138.  
  139.     IFD    WBENCH
  140.     tst.l    pr_CLI(a3)
  141.      beq.b    fromWorkbench
  142.     ENDC
  143.  
  144. *=======================================================================
  145. *====== CLI Startup Code ===============================================
  146. *=======================================================================
  147. *
  148. ; Entry: d2 = command length
  149. ;     a2 = Command pointer
  150. fromCLI:
  151.     move.l    sp,d0             ; get top of stack
  152.     sub.l    4(sp),d0        ; compute bottom 
  153.     add.l    #128,d0             ; allow for parms overflow
  154.     move.l    d0,__base(a4)        ; save for stack checking
  155.  
  156. * attempt to open DOS library
  157.     bsr.w    openDOS
  158.  
  159. * find command name:
  160.     move.l    pr_CLI(a3),a0
  161.     add.l    a0,a0             ; bcpl pointer conversion
  162.     add.l    a0,a0
  163.     move.l    cli_CommandName(a0),a1
  164.     add.l    a1,a1             ; bcpl pointer conversion
  165.     add.l    a1,a1
  166.  
  167. * collect parameters:
  168.     move.l    d2,d0            ; get command line length
  169.     moveq.l    #0,d1
  170.     move.b    (a1)+,d1
  171.     move.l    a1,__ProgramName(a4)
  172.     add.l    d1,d0            ; add length of command name
  173.     addq.l    #1,d0            ; allow for space after command 
  174.  
  175.     clr.w    -(sp)            ; set null terminator for command line
  176.     addq.l    #1,d0            ; force to even number of bytes
  177.     andi.w    #$fffe,d0        ; (round up)
  178.     sub.l    d0,sp            ; make room on stack for command line
  179.     subq.l    #2,d0
  180.     clr.w    0(sp,d0)
  181.  
  182. * copy command line onto stack
  183.     move.l    d2,d0            ; get command line length
  184.     subq.l    #1,d0
  185.     add.l    d1,d2
  186.  
  187. copy_line:
  188.     move.b    0(a2,d0.w),0(sp,d2.w)    ; copy command line to stack
  189.     subq.l    #1,d2
  190.     dbf    d0,copy_line
  191.     move.b    #' ',0(sp,d2.w)         ; add space between command and parms
  192.     subq.l    #1,d2
  193.  
  194. copy_cmd:
  195.     move.b    0(a1,d2.w),0(sp,d2.w)    ; copy command name to stack
  196.     dbf    d2,copy_cmd
  197.     move.l    sp,a1
  198.     move.l    a1,-(sp)        ; push command line address
  199.  
  200.     IFD    WBENCH
  201.     bra.b    main            ; call C entrypoint
  202. * --------------------------------------------------------------------- *
  203. * Workbench Startup Code
  204. * --------------------------------------------------------------------- *
  205. fromWorkbench:
  206.     move.l    TC_SPLOWER(a3),__base(a4) ; set base of stack
  207.     moveq     #127,d0
  208.     addq.l    #1,d0            ; Efficient way of getting in 128
  209.     add.l    d0,__base(a4)        ; allow for parms overflow
  210.  
  211. * open the DOS library:
  212.     bsr.w    openDOS
  213.  
  214. * we are now set up. wait for a message from our starter
  215.     lea    pr_MsgPort(a3),a0    ; our process base
  216.     SYS    WaitPort
  217.     lea    pr_MsgPort(a3),a0    ; our process base
  218.     SYS    GetMsg
  219.     move.l    d0,_WBenchMsg(a4)
  220.     move.l    d0,-(sp)
  221.  
  222.     move.l    d0,a2            ; get first argument
  223.     move.l    sm_ArgList(a2),d0
  224.      beq.b    do_cons
  225.     move.l    _DOSBase(a4),a6
  226.     move.l    d0,a0
  227.     move.l    wa_Lock(a0),d1
  228.     move.l    d1,_curdir(a4)
  229.     SYS    CurrentDir
  230. do_cons:
  231.     move.l    sm_ToolWindow(a2),d1    ; get the window argument
  232.      beq.b    do_main
  233.     move.l    #MODE_OLDFILE,d2
  234.     SYS    Open
  235.     move.l    d0,_stdin(a4)
  236.      beq.b    do_main
  237.     lsl.l    #2,d0
  238.     move.l    d0,a0
  239.     move.l    fh_Type(a0),pr_ConsoleTask(a3)
  240. do_main:
  241.     move.l    _WBenchMsg(a4),a0    ; get address of workbench message
  242.     move.l    a0,-(sp)        ; push argv
  243.     pea    _NULL(a4)        ; push argc
  244.     move.l    sm_ArgList(a0),a0    ; get address of arguments
  245.     move.l    wa_Name(a0),__ProgramName(a4)     ; get name of program
  246.     ENDC
  247.  
  248. * --------------------------------------------------------------------- *
  249. * Common CLI/WBENCH code
  250. * --------------------------------------------------------------------- *
  251. main:
  252.      IFD    FLOAT
  253.     jsr    ___fpinit(pc)        ; Initialize floating point
  254.      ENDC
  255.  
  256.     jsr    __main(pc)        ; call C entrypoint
  257.     moveq.l    #0,d0            ; set successful status
  258.     bra.b    exit2
  259.  
  260.     XDEF    _XCEXIT
  261. _XCEXIT:
  262.     move.l    4(sp),d0        ; extract return code
  263.  
  264.     XDEF    xXCEXIT
  265. xXCEXIT:
  266. exit2:
  267.     move.l    d0,-(sp)        ; save return status
  268.  
  269.      IFD    ERRTRAPS
  270.     move.l    __ONEXIT(a4),d0        ; exit trap function?
  271.      beq.b    exit3
  272.     move.l    d0,a0
  273.     jsr    (a0)
  274. exit3:
  275.      ENDC
  276.  
  277.      IFD    MALLOC
  278.     jsr    _MemCleanup(pc)        ; cleanup leftover memory alloc.
  279.      ENDC
  280.  
  281.     movea.l    AbsExecBase,a6
  282.     move.l    _DOSBase(a4),a1
  283.     SYS    CloseLibrary        ; close Dos library
  284.  
  285.      IFD    FLOAT
  286.     jsr    ___fpterm(pc)        ; clean up any floating point
  287.      ENDC
  288.  
  289.      IFD    WBENCH
  290. done_1c:
  291. * if we ran from CLI, skip workbench cleanup:
  292.     tst.l    _WBenchMsg(a4)
  293.      beq.b    exitToDOS
  294.     move.l    _stdin(a4),d1
  295.      beq.b    done_4
  296.     SYS    Close
  297. done_4:
  298. * return the startup message to our parent
  299. *     we forbid so workbench can't UnLoadSeg() us
  300. *     before we are done:
  301.     movea.l    AbsExecBase,a6
  302.     SYS    Forbid
  303.     move.l     _WBenchMsg(a4),a1
  304.     SYS    ReplyMsg
  305.      ENDC
  306.  
  307. * this rts sends us back to DOS:
  308. exitToDOS:
  309.      IFD    RESIDENT
  310.     move.l    #_RESLEN,d0
  311.     move.l     a4,a1
  312.     sub.l    #_RESBASE,a1
  313.     movea.l    AbsExecBase,a6
  314.     SYS    FreeMem
  315.      ENDC
  316.     
  317.     move.l    (sp)+,d0
  318.     movea.l    __StackPtr(a4),sp    ; restore stack ptr
  319.  
  320.     XDEF    xchkabort
  321. xchkabort:
  322.     rts
  323.  
  324.      IFD    RESIDENT
  325. abort:
  326.     movem.l    (sp)+,d0-d1/a0-a2
  327.     rts
  328.      ENDC
  329.  
  330. * --------------------------------------------------------------------- *
  331. noDOS:
  332.     moveq.l    #100,d0
  333.     bra.b    exit2
  334.  
  335. * --------------------------------------------------------------------- *
  336. *    Open the DOS library:
  337. * --------------------------------------------------------------------- *
  338. openDOS:
  339.     lea    DOSName(pc),a1
  340.     moveq.l #0,d0
  341.     SYS    OpenLibrary
  342.     move.l    d0,_DOSBase(a4)
  343.      beq.b    noDOS
  344.     rts
  345.  
  346. DOSName:    dc.b    'dos.library',0
  347.  
  348. * --------------------------------------------------------------------- *
  349.     SECTION __MERGED,BSS
  350. * --------------------------------------------------------------------- *
  351.  
  352.     XDEF    _NULL,_SysBase,_WBenchMsg
  353.     XDEF    _curdir,__mbase,__mnext,__msize,__tsize
  354.     XDEF    __oserr,__OSERR
  355.      IFD    FLOAT
  356.     XDEF    __FPERR
  357.     XDEF    __SIGFPE
  358.      ENDC
  359.      IFD    ERRTRAPS
  360.     XDEF    __ONERR,__ONEXIT,__ONBREAK
  361.     XDEF    __SIGINT
  362.      ENDC
  363.     XDEF    _stdin
  364.     XDEF    __ProgramName,__StackPtr,__base
  365.  
  366. * --------------------------------------------------------------------- *
  367. _NULL        ds.l    1         ; Huh?
  368. __base        ds.l    1         ; base of stack
  369. __mbase        ds.l    1         ; base of memory pool
  370. __mnext        ds.l    1         ; next available memory location
  371. __msize        ds.l    1         ; size of memory pool
  372. __tsize        ds.l    1         ; total size?
  373. __oserr
  374. __OSERR        ds.l    1
  375.      IFD    FLOAT
  376. __FPERR        ds.l    1
  377. __SIGFPE    ds.l    1
  378.      ENDC
  379.      IFD    ERRTRAPS
  380. __SIGINT    ds.l    1
  381. __ONERR        ds.l    1
  382. __ONEXIT    ds.l    1
  383. __ONBREAK    ds.l    1
  384.      ENDC
  385. _curdir        ds.l    1
  386. _SysBase    ds.l    1
  387. _WBenchMsg    ds.l    1
  388. __StackPtr    ds.l    1
  389. _stdin        ds.l    1
  390. __ProgramName    ds.l    1
  391.  
  392. * --------------------------------------------------------------------- *
  393.     END
  394. * --------------------------------------------------------------------- *
  395.